﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.UI;
using prismic.extensions;
using PrismicIOAPI.api;
using PrismicIOAPI.Util;
using Api = prismic.Api;

namespace PrismicIOAPI.Web.UI
{
    public abstract class PrismicControl : UserControl
    {
        public string PRISMIC_REF = null;
        private ContentController _contentController = null;
        private prismic.Api.Document pageDocument = null;
        private List<prismic.Api.Document> pageDocumentList = null;
        private static object lockobj = 1;

        protected virtual String DataSource { get; set; }

        /// <summary>
        /// 
        /// </summary>
        private ContentController Controller
        {
            get
            {
                if( _contentController == null )
                {
                    _contentController = new ContentController();
                    this.PRISMIC_REF = Request.QueryString[ "token" ];
                    if( this.PRISMIC_REF != null )
                    {
                        _contentController.PRISMIC_REF = this.PRISMIC_REF;
                    }
                }
                return _contentController;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        protected prismic.Api.Document PageDocument
        {
            get
            {
                if( pageDocument == null )
                {
                    var documents = FetchContent();
                    if( documents != null && documents.Count > 0 )
                    {
                        pageDocument = documents.FirstOrDefault();
                    }
                }
                return pageDocument;
            }
            set
            {
                pageDocument = value;
            }
        }

        protected List<prismic.Api.Document> PageDocumentList
        {
            get
            {
                if( pageDocumentList == null )
                {
                    pageDocumentList = new List<Api.Document>();
                    var documents = FetchContent();
                    if( documents != null && documents.Count > 0 )
                    {
                        int cn;
                        cn = 0;
                        while( cn < documents.Count )
                        {
                            pageDocumentList.Add( documents[ cn ] );
                            cn++;
                        }
                    }
                }
                return pageDocumentList;
            }
            set
            {
                pageDocumentList = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void BindControls() { }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="writer"></param>
        //public override void RenderControl(HtmlTextWriter writer)
        //{
        //    lock (lockobj)
        //    {
        //        string html = null;

        //        var ctrl_id = HttpContext.Current.Request.Url.AbsolutePath;

        //       // CacheController.GetCachedObject<String>(ref html, ctrl_id);
        //        if (html == null)
        //        {
        //            BindControls();
        //            StringBuilder sb = new StringBuilder();
        //            StringWriter tw = new StringWriter(sb);
        //            HtmlTextWriter hw = new HtmlTextWriter(tw);
        //            this.Render(hw);
        //            html = sb.ToString();
        //            CacheController.GetCachedObject<String>(ref html, ctrl_id);
        //        }
        //        writer.Write(html);
        //    }
        //}

        #region PrismicIO Helper Methods

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private String FormatURL( String Content )
        {
            string LIVE_SITE_URL = SiteSettings.LiveSiteUrl;
            string LIVE_SITE_URL2 = SiteSettings.LiveSiteSecondUrl;
            if( !String.IsNullOrEmpty( Content ) )
            {
                if( !String.IsNullOrEmpty( LIVE_SITE_URL ) )
                {
                    Content = Regex.Replace( Content , LIVE_SITE_URL , String.Empty , RegexOptions.IgnoreCase );
                }
                if( !String.IsNullOrEmpty( LIVE_SITE_URL2 ) )
                {
                    Content = Regex.Replace( Content , LIVE_SITE_URL2 , String.Empty , RegexOptions.IgnoreCase );
                }

            }
            return Content;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        protected List<prismic.Api.Document> FetchContent()
        {
            if( String.IsNullOrEmpty( DataSource ) )
            {
                return null;
            }
            List<prismic.Api.Document> documents = null;
            documents = Controller.Get( DataSource ) as List<prismic.Api.Document>;
            return documents;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="Document"></param>
        /// <param name="field"></param>
        /// <returns></returns>
        protected String GetText( prismic.Api.Document Document , String field )
        {
            string fragmentvalue = null;
            var fragment = Document.GetText( String.Format( "{0}.{1}" , Document.typ , field ) );
            if( fragment != null )
            {
                fragmentvalue = fragment.Value;
            }
            return fragmentvalue;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Document"></param>
        /// <param name="field"></param>
        /// <returns></returns>
        protected String GetText( prismic.Fragments.GroupDoc Document , String field )
        {
            string fragmentvalue = null;
            var fragment = Document.GetText( field );
            if( fragment != null )
            {
                fragmentvalue = fragment.Value;
            }
            return fragmentvalue;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="Document"></param>
        /// <param name="Element"></param>
        /// <param name="Thumbnail"></param>
        /// <returns></returns>
        protected String GetImageURL( prismic.Api.Document Document , String Element , String Thumbnail )
        {
            string url = null;
            if( String.IsNullOrEmpty( Thumbnail ) )
            {
                Thumbnail = "main";
            }

            var coverImageViewFragment = Document.GetImageView( String.Format( "{0}.{1}" , Document.typ , Element ) , Thumbnail );
            if( coverImageViewFragment != null )
            {
                url = coverImageViewFragment.Value.url;
            }
            return url;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Document"></param>
        /// <param name="?"></param>
        /// <returns></returns>
        protected String GetHTML( prismic.Api.Document Document )
        {
            string html = null;
            if( Document == null )
            {
                return html;
            }
            var resolver = prismic.extensions.DocumentLinkResolver.For( l => String.Format( "http://localhost/{0}/{1}" , l.typ , l.id ) );
            html = Document.AsHtml( resolver );
            return FormatURL( html );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Document"></param>
        /// <returns></returns>
        protected String GetHTML( prismic.Fragments.GroupDoc Document , String Field )
        {
            string html = String.Empty;
            if( Document == null )
            {
                return html;
            }
            var resolver = prismic.extensions.DocumentLinkResolver.For( l => String.Format( "http://localhost/{0}/{1}" , l.typ , l.id ) );
            var fragment = Document.Get( Field );
            if( fragment != null )
            {
                var fragHTML = fragment.BindAsHtml( resolver );
                if( fragHTML != null )
                {
                    html = fragHTML.Value;
                }
            }
            return FormatURL( html );
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="Document"></param>
        /// <param name="FragmentName"></param>
        /// <returns></returns>
        protected String GetHTML( prismic.Api.Document Document , String FragmentName )
        {
            String html = String.Empty;
            if( Document == null || String.IsNullOrEmpty( FragmentName ) )
            {
                return html;
            }
            var dSectionFrag = Document.Get( string.Format( "{0}.{1}" , Document.typ , FragmentName ) );
            if( dSectionFrag != null )
            {
                var resolver = prismic.extensions.DocumentLinkResolver.For( l => String.Format( "http://localhost/{0}/{1}" , l.typ , l.id ) );
                var fragmentContainer = dSectionFrag.BindAsHtml( resolver );
                if( fragmentContainer != null )
                {
                    html = fragmentContainer.Value;
                }
            }
            return FormatURL( html );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Document"></param>
        /// <param name="Field"></param>
        protected List<prismic.Fragments.GroupDoc> GetGroupContent( prismic.Api.Document Document , string Field )
        {
            List<prismic.Fragments.GroupDoc> content = null;
            ;
            var groupFragment = Document.Get( String.Format( "{0}.{1}" , Document.typ , Field ) );
            if( groupFragment != null )
            {
                var group = groupFragment.Value as prismic.Fragments.Fragment.Group;
                if( group != null )
                {
                    content = group.Item.ToList();
                }
            }
            return content;
        }

        #endregion PrismicIO Helper Methods

    }
}